import datetime
from sqlalchemy import Boolean, Column, ForeignKey, Integer, String, DateTime, Double
from sqlalchemy.orm import relationship

from database import Base


class Time(Base):
    __abstract__ = True

    id = Column(Integer, primary_key=True)
    created_at = Column(DateTime, nullable=False, default=datetime.datetime.now)
    updated_at = Column(DateTime, nullable=False, default=datetime.datetime.now, onupdate=datetime.datetime.now)
    state = Column(Boolean, default=True)


class App(Base):
    __tablename__ = "_app"

    id = Column(Integer, primary_key=True)
    version = Column(String)
    platform = Column(String)
    androidUrl = Column(String, nullable=True)
    appleStore = Column(String, nullable=True)
    created_at = Column(DateTime, nullable=True)


class Card(Time):
    __tablename__ = "_card"

    fee = Column(Double)
    bank = Column(String)

    user_id = Column(Integer, ForeignKey("_user.id"))
    user = relationship("User", back_populates="cards")


class Category(Time):
    __tablename__ = "_category"

    name = Column(String)

    user_id = Column(Integer, ForeignKey("_user.id"))
    user = relationship("User", back_populates="categories")


class Family(Time):
    __tablename__ = "_family"

    nickname = Column(String)

    family_id = Column(Integer, ForeignKey("_user.id"))
    family = relationship("User", back_populates="families2", foreign_keys=family_id)

    user_id = Column(Integer, ForeignKey("_user.id"))
    user = relationship("User", back_populates="families", foreign_keys=user_id)


class Project(Time):
    __tablename__ = "_project"

    name = Column(String)
    rate = Column(Double)
    fee = Column(Double)
    income = Column(Double)
    startTime = Column(DateTime)
    endTime = Column(DateTime)

    user_id = Column(Integer, ForeignKey("_user.id"))
    user = relationship("User", back_populates="projects")


class Record(Time):
    __tablename__ = "_record"

    fee = Column(Double)
    category = Column(String)
    description = Column(String)

    card_id = Column(Integer, ForeignKey("_card.id"))
    card = relationship("Card", uselist=False, backref="card")

    user_id = Column(Integer, ForeignKey("_user.id"))
    user = relationship("User", back_populates="records")


class Statistics(Time):
    __tablename__ = "_statistics"

    spend = Column(Double)
    deposit = Column(Double)
    finance = Column(Double)

    user_id = Column(Integer, ForeignKey("_user.id"))
    user = relationship("User", back_populates="statistics")


class User(Time):
    __tablename__ = "_user"

    phone = Column(String, unique=True)
    nickname = Column(String)
    cards = relationship("Card", back_populates="user", order_by="Card.updated_at.desc()", lazy="dynamic")
    records = relationship("Record", back_populates="user", order_by="Record.created_at.desc()", lazy="dynamic")
    statistics = relationship("Statistics", back_populates="user", lazy="dynamic")
    families = relationship("Family", back_populates="user", foreign_keys="Family.user_id", lazy="dynamic")
    families2 = relationship("Family", back_populates="family", foreign_keys="Family.family_id", lazy="dynamic")
    projects = relationship("Project", back_populates="user", order_by="Project.updated_at.desc()", lazy="dynamic")
    categories = relationship("Category", back_populates="user", order_by="Category.created_at.desc()", lazy="dynamic")

    deviceId = Column(String, nullable=True)
    pushId = Column(String, nullable=True)
    iosDeviceId = Column(String, nullable=True)

    def find_nickname(self, user_id):
        for f in self.families:
            if f.family_id == user_id:
                return f.nickname if f.nickname != '' else f.family.nickname
        return ''

    def scoped_ids(self):
        ids = [f.family_id for f in self.families.filter(Family.state == True)]
        ids.append(self.id)
        return ids
